package com.bing.bingPro.service.impl;

import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bing.bingPro.controller.dto.ZdBasicOrderDto;
import com.bing.bingPro.controller.vo.ZdBasicInfoVo;
import com.bing.bingPro.controller.vo.ZdCheckOrderVo;
import com.bing.bingPro.entity.DZoneInfo;
import com.bing.bingPro.entity.ZdBasicInfo;
import com.bing.bingPro.entity.ZdCheckOrder;
import com.bing.bingPro.mapper.DZoneInfoMapper;
import com.bing.bingPro.mapper.ZdCheckOrderMapper;
import com.bing.bingPro.service.ZdCheckOrderService;
import com.bing.bingPro.util.ProvinceUtil;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 29821
 * @description 针对表【zd_check_order(OLAP)】的数据库操作Service实现
 * @createDate 2023-07-17 10:58:33
 */
@Service
public class ZdCheckOrderServiceImpl extends ServiceImpl<ZdCheckOrderMapper, ZdCheckOrder>
        implements ZdCheckOrderService {

    @Resource
    private DZoneInfoMapper dZoneInfoMapper;

    @Override
    public IPage<ZdCheckOrderVo> zdCheckPageList(ZdBasicOrderDto zdBasicOrderDto) {
        IPage<ZdCheckOrderVo> voIPage = new Page<>();
        Page page = new Page(zdBasicOrderDto.getPageNum(),zdBasicOrderDto.getPageSize());
        String time = zdBasicOrderDto.getTime();
        String province = ProvinceUtil.getKeyProvince(zdBasicOrderDto.getProvince());

        IPage<ZdCheckOrder> zedPage = baseMapper.selectPage(page,Wrappers.lambdaQuery(ZdCheckOrder.class)
                .eq(CharSequenceUtil.isNotEmpty(zdBasicOrderDto.getProvince()), ZdCheckOrder::getProvinceCode, province)
                .eq(CharSequenceUtil.isNotEmpty(time), ZdCheckOrder::getDt, time));
        List<ZdCheckOrder> zeds = zedPage.getRecords();

        List<Long> cityCodes = zeds.stream()
                .filter(z -> CharSequenceUtil.isNotEmpty(z.getCityCode()))
                .map(z -> Long.parseLong(z.getCityCode()))
                .distinct()
                .collect(Collectors.toList());

        List<DZoneInfo> dZoneInfos = dZoneInfoMapper.selectByZoneIds(cityCodes);
        Map<Integer, DZoneInfo> regionInfoMap = dZoneInfos.stream()
                .collect(Collectors.toMap(DZoneInfo::getZoneId, Function.identity(), (existingValue, newValue) -> newValue));

        List<Long> regionCodes = zeds.stream()
                .filter(z -> CharSequenceUtil.isNotEmpty(z.getRegionCode()))
                .map(z -> Long.parseLong(z.getRegionCode()))
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, DZoneInfo> zoneInfoMap;
        if (!regionCodes.isEmpty()) {
            List<DZoneInfo> regionInfos = dZoneInfoMapper.selectByZoneIds(regionCodes);
            zoneInfoMap = regionInfos.stream().collect(Collectors.toMap(DZoneInfo::getZoneId, Function.identity(), (existingValue, newValue) -> newValue));
        } else {
            zoneInfoMap = Collections.emptyMap();
        }

        List<ZdCheckOrderVo> collect = zeds.stream().map(zdBasicInfo -> {
            ZdCheckOrderVo vo = new ZdCheckOrderVo();
            BeanUtils.copyProperties(zdBasicInfo, vo);
            vo.setProvinceCode(ProvinceUtil.getProvince(zdBasicInfo.getProvinceCode()));

            if (CharSequenceUtil.isNotEmpty(zdBasicInfo.getCityCode())) {
                Integer zoneId = Integer.parseInt(zdBasicInfo.getCityCode());
                DZoneInfo dZoneInfo = regionInfoMap.get(zoneId);
                vo.setCityCode(dZoneInfo.getZoneName());
            }
            if (CharSequenceUtil.isNotEmpty(zdBasicInfo.getRegionCode())) {
                Integer regionID = Integer.parseInt(zdBasicInfo.getRegionCode());
                DZoneInfo region = zoneInfoMap.get(regionID);
                vo.setRegionCode(region.getZoneName());
            }
            return vo;
        }).collect(Collectors.toList());
        voIPage.setRecords(collect);
        voIPage.setTotal(zedPage.getTotal());
        voIPage.setPages(zedPage.getPages());
        voIPage.setCurrent(zedPage.getCurrent());
        voIPage.setSize(zedPage.getSize());
        return voIPage;
    }

    @Override
    public List<ZdCheckOrderVo> zdBasicList(ZdBasicOrderDto zdBasicOrderDto) {
        String time = zdBasicOrderDto.getTime();
        String province = ProvinceUtil.getKeyProvince(zdBasicOrderDto.getProvince());

        List<ZdCheckOrder> zeds = baseMapper.selectList(Wrappers.lambdaQuery(ZdCheckOrder.class)
                .eq(CharSequenceUtil.isNotEmpty(zdBasicOrderDto.getProvince()), ZdCheckOrder::getProvinceCode, province)
                .eq(CharSequenceUtil.isNotEmpty(time), ZdCheckOrder::getDt, time));

        List<Long> cityCodes = zeds.stream()
                .filter(z -> CharSequenceUtil.isNotEmpty(z.getCityCode()))
                .map(z -> Long.parseLong(z.getCityCode()))
                .distinct()
                .collect(Collectors.toList());

        List<DZoneInfo> dZoneInfos = dZoneInfoMapper.selectByZoneIds(cityCodes);
        Map<Integer, DZoneInfo> regionInfoMap = dZoneInfos.stream().collect(Collectors.toMap(DZoneInfo::getZoneId, Function.identity()));

        List<Long> regionCodes = zeds.stream()
                .filter(z -> CharSequenceUtil.isNotEmpty(z.getRegionCode()))
                .map(z -> Long.parseLong(z.getRegionCode()))
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, DZoneInfo> zoneInfoMap;
        if (!regionCodes.isEmpty()) {
            List<DZoneInfo> regionInfos = dZoneInfoMapper.selectByZoneIds(regionCodes);
            zoneInfoMap = regionInfos.stream().collect(Collectors.toMap(DZoneInfo::getZoneId, Function.identity()));
        } else {
            zoneInfoMap = Collections.emptyMap();
        }

        return zeds.stream().map(zdBasicInfo -> {
            ZdCheckOrderVo vo = new ZdCheckOrderVo();
            BeanUtils.copyProperties(zdBasicInfo, vo);
            vo.setProvinceCode(ProvinceUtil.getProvince(zdBasicInfo.getProvinceCode()));

            Integer zoneId = Integer.parseInt(zdBasicInfo.getCityCode());
            DZoneInfo dZoneInfo = regionInfoMap.get(zoneId);
            vo.setCityCode(dZoneInfo.getOrderName());
            if (CharSequenceUtil.isNotEmpty(zdBasicInfo.getRegionCode())) {
                Integer regionID = Integer.parseInt(zdBasicInfo.getRegionCode());
                DZoneInfo region = zoneInfoMap.get(regionID);
                vo.setRegionCode(region.getOrderName());
            }
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<ZdCheckOrderVo> zdCheckList(ZdBasicOrderDto zdBasicOrderDto) {
        String time = zdBasicOrderDto.getTime();
        String province = ProvinceUtil.getKeyProvince(zdBasicOrderDto.getProvince());

        List<ZdCheckOrder> zdCheckOrders = baseMapper.selectList(Wrappers.lambdaQuery(ZdCheckOrder.class)
                .eq(CharSequenceUtil.isNotEmpty(zdBasicOrderDto.getProvince()), ZdCheckOrder::getProvinceCode, province)
                .eq(CharSequenceUtil.isNotEmpty(time), ZdCheckOrder::getDt, time));

        Map<Integer, DZoneInfo> regionInfoMap = getIntegerDZoneInfoMap(zdCheckOrders);

        List<Long> regionCodes = zdCheckOrders.stream()
                .filter(z -> CharSequenceUtil.isNotEmpty(z.getRegionCode()))
                .map(z -> Long.parseLong(z.getRegionCode()))
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, DZoneInfo> zoneInfoMap;
        if (!regionCodes.isEmpty()) {
            List<DZoneInfo> regionInfos = dZoneInfoMapper.selectByZoneIds(regionCodes);
            zoneInfoMap = regionInfos.stream().collect(Collectors.toMap(DZoneInfo::getZoneId, Function.identity(), (existingValue, newValue) -> newValue));
        } else {
            zoneInfoMap = Collections.emptyMap();
        }

        return zdCheckOrders.stream().map(getZdCheckOrderZdCheckOrderVoFunction(regionInfoMap, zoneInfoMap)).collect(Collectors.toList());
    }

    @NotNull
    private Map<Integer, DZoneInfo> getIntegerDZoneInfoMap(List<ZdCheckOrder> zdCheckOrders) {
        List<Long> cityCodes = zdCheckOrders.stream()
                .filter(z -> CharSequenceUtil.isNotEmpty(z.getCityCode()))
                .map(z -> Long.parseLong(z.getCityCode()))
                .distinct()
                .collect(Collectors.toList());

        List<DZoneInfo> dZoneInfos = dZoneInfoMapper.selectByZoneIds(cityCodes);
        return dZoneInfos.stream().collect(Collectors.toMap(DZoneInfo::getZoneId, Function.identity(), (existingValue, newValue) -> newValue));
    }

    @NotNull
    private Function<ZdCheckOrder, ZdCheckOrderVo> getZdCheckOrderZdCheckOrderVoFunction(Map<Integer, DZoneInfo> regionInfoMap, Map<Integer, DZoneInfo> zoneInfoMap) {
        return zdBasicInfo -> {
            ZdCheckOrderVo vo = new ZdCheckOrderVo();
            BeanUtils.copyProperties(zdBasicInfo, vo);
            vo.setProvinceCode(ProvinceUtil.getProvince(zdBasicInfo.getProvinceCode()));
            if (CharSequenceUtil.isNotEmpty(zdBasicInfo.getCityCode())) {
                Integer zoneId = Integer.parseInt(zdBasicInfo.getCityCode());
                DZoneInfo dZoneInfo = regionInfoMap.get(zoneId);
                vo.setCityCode(dZoneInfo.getZoneName());
            }
            if (CharSequenceUtil.isNotEmpty(zdBasicInfo.getRegionCode())) {
                Integer regionID = Integer.parseInt(zdBasicInfo.getRegionCode());
                DZoneInfo region = zoneInfoMap.get(regionID);
                vo.setRegionCode(region.getZoneName());
            }
            return vo;
        };
    }
}




